package com.gandong8.derby.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.SecureUtil;
import com.gandong8.derby.core.constant.DOConstant;
import com.gandong8.derby.core.response.ResponseData;
import com.gandong8.derby.core.util.CollectCopyUtil;
import com.gandong8.derby.core.util.DESUtil;
import com.gandong8.derby.core.util.RequestUtil;
import com.gandong8.derby.dao.manual.WebSiteMapper;
import com.gandong8.derby.pojo.entry.manual.WebSite;
import com.gandong8.derby.pojo.vo.request.WebSiteReqVO;
import com.gandong8.derby.pojo.vo.response.WebSiteResVO;
import com.gandong8.derby.service.WebSiteService;
import lombok.extern.slf4j.Slf4j;
import org.jasypt.util.text.BasicTextEncryptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Service
@Slf4j
public class WebSiteServiceImpl implements WebSiteService{
    @Autowired
    WebSiteMapper webSiteMapper;

    @Override
    public void createTableIfNotExist(){
        try {
            webSiteMapper.count();
        } catch (DataAccessResourceFailureException e3) {
            String ddd = e3.getMessage();
            if(ddd.contains("Schema 'ROOT' does not exist")){
                try {
                    webSiteMapper.createTable();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }

            }else{
                e3.printStackTrace();
            }
        }catch (BadSqlGrammarException e) {
            if(e.getSQLException().getSQLState().equals("42X05")){
                try {
                    webSiteMapper.createTable();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }

            }else{
                e.printStackTrace();
            }

        }catch(Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public ResponseData siteAdd(WebSiteReqVO webSiteReqVO) {
        WebSite webSite = new WebSite();
        BeanUtil.copyProperties(webSiteReqVO, webSite);
        webSite.setAddTime(new Date());
        webSite.setEditTime(webSite.getAddTime());
        if(webSite.getDescription()==null) {
            webSite.setDescription("");
        }
        encAccount(webSite);
        webSiteMapper.insert(webSite);
        return ResponseData.succ();
    }

    @Override
    public WebSiteResVO siteInfo(WebSiteReqVO webSiteReqVO) {
        WebSiteResVO resVO = new WebSiteResVO();
        if(webSiteReqVO.getId()==null) {
            return resVO;
        }
        WebSite webSite = webSiteMapper.info(webSiteReqVO.getId());
        decAccount(webSite);
        BeanUtil.copyProperties(webSite, resVO);
        return resVO;
    }

    @Override
    public ResponseData siteEdit(WebSiteReqVO webSiteReqVO) {
        if(webSiteReqVO.getId()==null) {
            return ResponseData.fail("id is null");
        }
        WebSite webSite = new WebSite();
        BeanUtil.copyProperties(webSiteReqVO, webSite);
        webSite.setEditTime(new Date());
        encAccount(webSite);
        webSiteMapper.update(webSite);
        return ResponseData.succ();
    }

    @Override
    public ResponseData siteDel(WebSiteReqVO webSiteReqVO) {
        if(webSiteReqVO.getId()==null) {
            return ResponseData.fail("id is null");
        }
        webSiteMapper.deleteById(webSiteReqVO.getId());
        return ResponseData.succ("delete succ!");
    }

    @Override
    public ResponseData siteList(WebSiteReqVO webSiteReqVO) {
        int count = webSiteMapper.count();
        if(count < 1) {
            return ResponseData.succPage(new ArrayList<>(), 0);
        }
        webSiteReqVO.setOffset((webSiteReqVO.getPage()-1)*webSiteReqVO.getLimit());
        List<WebSite> webSiteList = webSiteMapper.queryByPage(webSiteReqVO);
        webSiteList.forEach(this::decAccount);
        List<WebSiteResVO> webSiteResVOs = new ArrayList<>();
        CollectCopyUtil.copyListProperties(webSiteList, webSiteResVOs, WebSiteResVO.class);
        return ResponseData.succPage(webSiteResVOs, count);
    }

    @Value("${site.user.salt}")
    String siteUserSalt;
    @Value("${site.pwd.salt}")
    String sitePwdSalt;
    final String account_tag = "_no_secret_";
    final String default_str = "******";

    private void encAccount(WebSite webSite) {
        String secret = (String) RequestUtil.getSession(DOConstant.SITE_SECRET);
        if(StringUtils.isEmpty(secret)) {
            webSite.setUsername(account_tag + webSite.getUsername() + account_tag);
            webSite.setPassword(account_tag + webSite.getPassword() + account_tag);
            return;
        }
        secret = SecureUtil.md5(secret);
        try {
            webSite.setUsername(DESUtil.encrypt(webSite.getUsername()+siteUserSalt + secret, siteUserSalt));
            webSite.setPassword(DESUtil.encrypt(webSite.getPassword()+sitePwdSalt + secret, sitePwdSalt));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void decAccount(WebSite webSite) {
        String secret = (String) RequestUtil.getSession(DOConstant.SITE_SECRET);
        if(webSite.getUsername().contains(account_tag)) {
            webSite.setUsername(webSite.getUsername().replace(account_tag, ""));
            webSite.setPassword(webSite.getPassword().replace(account_tag, ""));
            return;
        }
        if(StringUtils.isEmpty(secret)) {
            webSite.setUsername(default_str);
            webSite.setPassword(default_str);
            return;
        }
        secret = SecureUtil.md5(secret);
        try {
            String user = DESUtil.decrypt(webSite.getUsername(), siteUserSalt);
            if(user.contains(siteUserSalt + secret)) {
                webSite.setUsername(user.replace(siteUserSalt + secret,""));
            } else {
                webSite.setUsername(default_str);
            }
            String pwd = DESUtil.decrypt(webSite.getPassword(), sitePwdSalt);
            if(pwd.contains(sitePwdSalt + secret)) {
                webSite.setPassword(pwd.replace(sitePwdSalt + secret, ""));
            } else {
                webSite.setPassword(default_str);
            }
        } catch (Exception e) {
            webSite.setUsername(default_str);
            webSite.setPassword(default_str);
            e.printStackTrace();
        }
    }
}
